package com.tobeface.wechat.request;

import com.tobeface.modules.lang.Langs;
import com.tobeface.modules.lang.Requires;

/**
 * @author loudyn
 */
public final class RetryWeChatRequestStrategy implements WeChatRequestStrategy {

    private static final int DEFAULT_RETRY_TIMES = 3;
    private final int retryTimes;

    /**
     *
     */
    public RetryWeChatRequestStrategy() {
        this(DEFAULT_RETRY_TIMES);
    }

    /**
     * @param retryTimes
     */
    public RetryWeChatRequestStrategy(int retryTimes) {
        Requires.isTrue(retryTimes > 0 && retryTimes < 99);
        this.retryTimes = retryTimes;
    }

    @Override
    public WeChatResponse perform(WeChatRequestSinker sinker, WeChatRequest req) {
        int retryTimes = this.retryTimes;
        while (retryTimes-- > 0) {
            try {

                return sinker.sinkRequest(req);
            } catch (Exception e) {
                if (canRetry(retryTimes, e)) {
                    continue;
                }
                throw Langs.toUncheck(e);
            }
        }

        // never reach code.
        throw Langs.impossiable();
    }

    private boolean canRetry(int retryTimes, Exception e) {
        return retryTimes > 0 && isExceptionRecoverable(e);
    }

    private boolean isExceptionRecoverable(Exception e) {
        // TODO
        return true;
    }
}
